/**
  * <br>JAVACC DEMO 1.0<br>
  * @copy right dwusoft company All rights reserved.<br>
  * <br>
  * @Package com.dwusoft.platform.interceptor
*/
package com.dwusoft.platform.interceptor;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.apache.api.vo.Token;
import com.apache.cache.util.Validator;
import com.apache.exception.BusinessException;
import com.apache.license.validator.LicenseValidate;
import com.apache.tools.OsUtils;

/**
  * description: 防止数据重复提交拦截器
  * 用法：在表里加入<input type="hidden" name="formToken" value="${formToken}" />
  * 在需要生成token的controller上增加@Token(save=true)，而在需要检查重复提交的controller上添加@Token(remove=true)就可以了
  * 如：initSave()方法上加@Token(save=true); doSave()方法上加@Token(remove=true)
  * @author Hou DaYu 创建时间：下午06:26:36
  */
public class TokenInterceptor extends HandlerInterceptorAdapter {

	/**
	 * 方法执行前拦截
	 */
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

		if (handler instanceof HandlerMethod) {//方法级拦截
			//HandlerMethod handlerMethod = (HandlerMethod) handler;
			boolean mark = doLicense(request, response);
			if (!mark)
				return false;

			Method method = ((HandlerMethod) handler).getMethod();
			Token annotation = method.getAnnotation(Token.class);
			if (annotation != null) {
				boolean needSaveSession = annotation.save();
				if (needSaveSession) {//加入token
					HttpSession session = request.getSession(true);
					String uuid = UUID.randomUUID().toString();
					if (null != session)
						session.setAttribute("formToken", uuid);
				}
				boolean needRemoveSession = annotation.remove();
				if (needRemoveSession) {//移出token
					if (isRepeatSubmit(request)) {
						return false;
					}
					request.setAttribute("formToken", request.getSession(false).getAttribute("formToken"));
					request.getSession(false).removeAttribute("formToken");
				}
			}
			return true;
		} else {
			return super.preHandle(request, response, handler);
		}
	}

	/**
	 * 判断是否重复提交
	 */
	private boolean isRepeatSubmit(HttpServletRequest request) {
		String serverToken = Validator.getDefaultStr(
				String.valueOf(request.getSession(false).getAttribute("formToken")), "");
		if (Validator.isNull(serverToken)) {
			return true;
		}
		String clinetToken = request.getParameter("formToken");
		if (Validator.isNull(clinetToken)) {
			return true;
		}
		if (!serverToken.equals(clinetToken)) {
			return true;
		}
		return false;
	}

	/**
	 * license验证
	 */
	private boolean doLicense(HttpServletRequest request, HttpServletResponse response) throws BusinessException {
		String path = request.getRequestURI();
		try {
			long lastTime = LicenseValidate.getInstance().isTimeByDay(30);//返回要提醒的天数
			if (lastTime == -1) {
				response.sendRedirect(request.getContextPath() + "/errorPage?Errorcode=ZBXSOFT-00000001");//License 超过有效期！
				return false;
			} else {
				if (lastTime <= 30) {//有效期验证
					/////////////////license将到期提醒操作////////////////////
					warnLicenseInfo(request, response, lastTime);
				}
			}

			if (LicenseValidate.getInstance().isFormal()) {//正式license号
				if (path.indexOf("errorPage") != -1) {
					return true;
				}
				boolean isIp = LicenseValidate.getInstance().isip(OsUtils.getLocalIp());
				boolean isMac = LicenseValidate.getInstance().ismac(OsUtils.getMACAddress());
				if (!LicenseValidate.getInstance().isEffective()) {
					response.sendRedirect(request.getContextPath() + "/errorPage?Errorcode=ZBXSOFT-00000002");//服务器IP或mac地址未授权
					return false;
				}
			}
		} catch (Exception e) {
			try {//服务器IP或mac地址未授权
				if (path.indexOf("error") != -1 || path.indexOf("invalid.jsp") != -1) {
					return true;
				}
				response.sendRedirect(request.getContextPath() + "/errorPage");
			} catch (IOException e1) {
			}
			return false;
		}
		return true;
	}

	/**
	 * 提示用户license即将到期
	 */
	protected void warnLicenseInfo(HttpServletRequest request, HttpServletResponse response, long lastTime) {
		request.getSession().setAttribute("licenseTodata", lastTime);
	}
}
